//
//  UIView+JumpNumber.m
//  xieyingze
//
//  Created by xieyingze on 16/5/9.
//  Copyright © 2016年 xieyingze. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <objc/runtime.h>

typedef void(^ChangeNumberBlock)(NSString *);
@interface BlockModel : NSObject

@property (nonatomic, copy) ChangeNumberBlock changeBlock;
@end
@implementation BlockModel

@end


#import "UIView+JumpNumber.h"
#import "NJDBezierCurve.h"


static NSString *kAssociatedObject;

static NSString *kIndexNumber = @"kIndexNumber";
static NSString *kLastTime = @"kLastTime";
static NSString *kNumberPoints = @"kNumberPoints";
static NSString *kChangeBlock = @"kChangeBlock";


@implementation UIView (JumpNumber)

#pragma mark - 变量

//贝塞尔曲线控制点
Point2D startPointMe;
Point2D controlPoint1Me;
Point2D controlPoint2Me;
Point2D endPointMe;


//滚动相关
int             _totalNumberMe = 100;//跳动总次数



void(^_changeNumber)(NSString *);//改变value

#pragma mark - 方法
- (void)jumpNumberWithDuration:(int)duration
                    fromNumber:(float)startNumber
                      toNumber:(float)endNumber
                    completion:(void(^)(BOOL isFinished))completion {
    if (fabs(startNumber - endNumber) < 0.5){
        completion(YES);
       return;
    }

//    if(completion) _completionMe = completion;
    
    [self initdata];
    [self initBezierPoints];
    [self initPointsWithDuration:duration  fromNumber:startNumber toNumber:endNumber];
    [self changeIntNumberBySelector:completion];
}

#pragma mark 数据准备
- (ChangeNumberBlock)initBlock {
    if ([self isKindOfClass:[UIButton class]]) {
        __weak UIButton *temp = (UIButton *)self;
        return ^(NSString *number) {
            [temp setTitle:number forState:temp.state];
        };

    }
    else if ([self isKindOfClass:[UILabel class]]       ||
             [self isKindOfClass:[UITextField class]]   ||
             [self isKindOfClass:[UITextView class]]) {
        __weak UILabel *temp = (UILabel *)self;
        return  ^(NSString *number){
            [temp setText:number];
        };
    }
    return ^(NSString *number){
    };
}
- (void)initdata {
    //block不能作为对象放在dict中，所以借助model的属性
    BlockModel *model = [[BlockModel alloc]init];
    model.changeBlock = [self initBlock];
    //默认数据
    NSMutableDictionary *dict = objc_getAssociatedObject(self, &kAssociatedObject);
    if (!dict){
        dict = [[NSMutableDictionary alloc]initWithCapacity:4];
    }
    [dict setObject:[NSNumber numberWithInteger:0] forKey:kIndexNumber];
    [dict setObject:[NSNumber numberWithDouble:0.f] forKey:kLastTime];
    [dict setObject:model forKey:kChangeBlock];
    objc_setAssociatedObject(self, &kAssociatedObject, dict, OBJC_ASSOCIATION_RETAIN);//绑定indexNumber，lastTime，block
}
- (void)initBezierPoints {//初始化贝塞尔曲线控制点
    // 可到http://cubic-bezier.com自定义贝塞尔曲线
    
    startPointMe.x = 0;
    startPointMe.y = 0;
    
    controlPoint1Me.x = 0.25;
    controlPoint1Me.y = 0.1;
    
    controlPoint2Me.x = 0.25;
    controlPoint2Me.y = 1;
    
    endPointMe.x = 1;
    endPointMe.y = 1;
}

- (void)initPointsWithDuration:(float)duration  fromNumber:(float)startNumber toNumber:(float)endNumber {//根据贝塞尔曲线计算_totalNumberMe个曲线上的点，即计算出每次跳动到的数字和时间
    
    Point2D bezierCurvePoints[4] = {startPointMe,controlPoint1Me,controlPoint2Me,endPointMe};
    NSMutableArray *points = [[NSMutableArray alloc]init];
    float dt = 1.0 / (_totalNumberMe - 1);
    for (int i = 0; i < _totalNumberMe; i ++) {
        Point2D point = PointOnCubicBezier(bezierCurvePoints, i * dt);
        int durationTime = point.x * duration;
        float value = point.y * (endNumber - startNumber) + startNumber;
        [points addObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:durationTime],[NSNumber numberWithFloat:value], nil]];
    }
    NSMutableDictionary *dict = objc_getAssociatedObject(self, &kAssociatedObject);
    if (!dict){
        dict = [[NSMutableDictionary alloc]initWithCapacity:4];
    }
    [dict setObject:points forKey:kNumberPoints];
    
}
#pragma mark 跳动
- (void)changeNumberBySelector:(void(^)(BOOL isFinished))completion {
    //取值
    NSMutableDictionary *dict = objc_getAssociatedObject(self, &kAssociatedObject);
    NSInteger indexNumber = [[dict objectForKey:kIndexNumber] integerValue];
    CGFloat lastTime = [[dict objectForKey:kLastTime] floatValue];
    
    if (indexNumber >= _totalNumberMe) {//跳动100次
        if (completion) completion(YES);
        return;
    }
    else {
        //取值
        NSArray *numberPoints = [dict objectForKey:kNumberPoints];
        ChangeNumberBlock block = ((BlockModel *)[dict objectForKey:kChangeBlock]).changeBlock;
        
        NSArray *pointValues = [numberPoints objectAtIndex:indexNumber];
        indexNumber ++;
        double value = [[pointValues lastObject] doubleValue];
        float currentTime = [[pointValues firstObject] doubleValue];
        float timeDuration = currentTime - lastTime;
        lastTime = currentTime;
        block([NSString stringWithFormat:@"%.2f",value]);//赋值
        
        //重新赋值
        [dict setObject:[NSNumber numberWithInteger:indexNumber] forKey:kIndexNumber];
        [dict setObject:[NSNumber numberWithDouble:lastTime] forKey:kLastTime];
        
        [self performSelector:@selector(changeNumberBySelector:) withObject:completion afterDelay:timeDuration];
    }
}

- (void)changeIntNumberBySelector:(void(^)(BOOL isFinished))completion {
    //取值
    NSMutableDictionary *dict = objc_getAssociatedObject(self, &kAssociatedObject);
    NSInteger indexNumber = [[dict objectForKey:kIndexNumber] integerValue];
    CGFloat lastTime = [[dict objectForKey:kLastTime] floatValue];
    
    if (indexNumber >= _totalNumberMe) {//跳动100次
        if (completion) completion(YES);
        return;
    }
    else {
        //取值
        NSArray *numberPoints = [dict objectForKey:kNumberPoints];
        ChangeNumberBlock block = ((BlockModel *)[dict objectForKey:kChangeBlock]).changeBlock;
        
        NSArray *pointValues = [numberPoints objectAtIndex:indexNumber];
        indexNumber ++;
        int value = [[pointValues lastObject] intValue];
        int currentTime = [[pointValues firstObject] intValue];
        int timeDuration = currentTime - lastTime;
        lastTime = currentTime;
        block([NSString stringWithFormat:@"%d",value]);//赋值
        
        //重新赋值
        [dict setObject:[NSNumber numberWithInteger:indexNumber] forKey:kIndexNumber];
        [dict setObject:[NSNumber numberWithDouble:lastTime] forKey:kLastTime];
        
        [self performSelector:@selector(changeNumberBySelector:) withObject:completion afterDelay:timeDuration];
    }
}


#pragma mark - 只是想分割
- (void)jumpNumberWithFromNumber:(float)startNumber
                        toNumber:(float)endNumber
                      completion:(void(^)(BOOL isFinished))completion {
    [self jumpNumberWithDuration:2 fromNumber:startNumber toNumber:endNumber completion:completion];//默认2秒执行时间
}


- (void)jumpNumberWithDuration:(int)duration
                    fromString:(NSString *)startStr
                      toString:(NSString *)endString
                    completion:(void(^)(BOOL isFinished))completion {
    [self jumpNumberWithDuration:duration fromNumber:[[self removeMoneyFomart:startStr] doubleValue] toNumber:[[self removeMoneyFomart:endString] doubleValue] completion:completion];
}

- (void)jumpNumberWithFromString:(NSString *)startStr
                        toString:(NSString *)endString
                      completion:(void(^)(BOOL isFinished))completion {
    [self jumpNumberWithFromNumber:[[self removeMoneyFomart:startStr] doubleValue] toNumber:[[self removeMoneyFomart:endString] doubleValue] completion:completion];
}

- (NSString *)removeMoneyFomart:(NSString *)str{
    return [[str componentsSeparatedByString:@","] componentsJoinedByString:@""];
}
@end
